<template>
  <div
    v-loading="loading"
    element-loading-text="文件上传中..."
    style="border: 1px solid #ccc"
    class="content flex flex-col h-full w-full"
  >
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      class="flex-1"
      :style="disabled ? 'pointer-events: none;' : ''"
      style="height: 100%; overflow-y: hidden"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChange"
      @onMaxLength="handleMaxLength"
    />
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  onBeforeUnmount,
  shallowRef,
  onMounted,
  reactive,
  toRefs,
  watch,
} from "vue";
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ElMessage } from "element-plus";
import { _post_topic_img } from "@/api/flow";

export default defineComponent({
  components: { Editor, Toolbar },
  emits: ["update:modelValue", "change"],
  props: {
    modelValue: {
      type: String,
      default: "",
    },
    // 编辑器提示信息
    placeholder: {
      type: String,
      default: "请输入内容...",
    },
    // 模式（'default'经典模式 或 'simple'精简模式）
    mode: {
      type: String,
      default: "default",
    },
    //禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    maxLength: {
      type: Number,
      default: 1000,
    },
    // 是否必填
    required: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { emit }) {
    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef();
    const editorConfig = {
      placeholder: props.placeholder,
      maxLength: props.maxLength,
      MENU_CONF: {
        ["uploadImage"]: {
          async customUpload(file: any, insertFn: any) {
            const formData = new FormData();
            formData.append("file", file);
            formData.append("purpose", "8");
            edit.loading = true;
            // 图片上传配置及接口调用
            _post_topic_img(formData)
              .then((res: any) => {
                if (res) {
                  insertFn(res.filePath);
                  ElMessage.success("上传成功");
                  edit.loading = false;
                } else {
                  ElMessage.warning("文件上传失败！");
                  edit.loading = false;
                }
              })
              .catch((err: any) => {
                console.log(err);
              });
          },
        },
      } as any,
    } as any; //编辑器配置
    const edit = reactive({
      valueHtml: props.modelValue, //内容 HTML
      loading: false,
      // 编辑器创建完毕时的回调函数。
      handleCreated: (editor: any) => {
        editorRef.value = editor; // 记录 editor 实例，重要！
        if (props.disabled) editorRef.value.disabled = true;
      },
      handleMaxLength: () => {
        ElMessage.warning(`当前字数已达到最大限制字数${props.maxLength}`);
      },
      // 编辑器内容、选区变化时的回调函数。
      handleChange: (editor: any) => {
        if (edit.valueHtml == "<p><br></p>" && props.required) {
          emit("update:modelValue", "");
        } else {
          emit("update:modelValue", edit.valueHtml);
        }
        emit("change");
      },
    });
    const toolbars = reactive({
      toolbarConfig: {
        excludeKeys: [
          //筛选出不要的工具栏（打开调试工具复制，选择对应DOM,data-menu-key后面的值为该工具名称，复制即可）
          "group-video", //插入视频和上传视频
          "insertImage", //去掉图片上传中网络图片选项
          "blockquote", //引用
          "bulletedList", //无序列表
          "numberedList", //有序列表
          "todo", //代办
          "emotion", //表情
          "insertLink", //插入链接
          "codeBlock", //代码块
          "divider", //分割线
          "fullScreen", //全屏
          "undo", //撤销
          "redo", //重做
        ],
      } as any, //工具栏配置
    });

    watch(
      () => props.modelValue,
      (n, o) => {
        edit.valueHtml = n;
      }
    );
    onMounted(() => {});
    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
      const editor = editorRef.value;
      if (editor == null) return;
      editor.destroy();
    });
    return {
      ...toRefs(edit),
      ...toRefs(toolbars),
      editorRef,
      editorConfig,
    };
  },
});
</script>

<style lang="scss" scoped>
.content {
  display: flex;
  flex-direction: column;
  width: 100% !important;
  height: 100% !important;
  padding: 40px;
}
</style>
